home *** CD-ROM | disk | FTP | other *** search
- #include <conio.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <mem.h>
-
- #define KEYCHARS 16
- #define KEYBITS KEYCHARS * 8
- #define XORCHARS 122
- #define XORBITS XORCHARS * 8
- #define EQUATIONS XORBITS + 32
- #define KEYSIZE KEYBITS * (KEYBITS + 1)
- #define XORSIZE XORBITS * (KEYBITS + 1)
-
- char huge TabKey[KEYBITS][KEYBITS+1]; // password
- char huge TabCipher[EQUATIONS][KEYBITS+1]; // table for XOR
- char AktKey[32][KEYBITS+1]; // current key
- char Temp[2][KEYBITS+1]; // temporary for ROL
- char TabPass[KEYBITS]; // password divided into bits
- char password[KEYCHARS];
- char TempEqu[12 * 8 + 1]; // temp for swap_equ
- unsigned char solved[EQUATIONS];
-
- FILE *org;
- char passsize;
- char size_pass[] = {11, 14, 14, 14};
- char passchars = 0, passbits = 0;
-
- void do_test(void);
- void do_xor(char huge *, char huge *);
- void do_xor_equ(int, int);
- void swap_equ(int, int);
- char compute_char(int);
- unsigned long compute_eax(void);
- void create_table(void);
- int create_equations(void);
- int solve(void);
- int check_equation(int, int);
- void show_pass(int);
- void insert_values(void);
- int search(int, int);
- void set_eax(void);
-
- main()
- {
- cputs("\r\n╔══════════════════════════════════════════════════════════════════════════════╗");
- cputs("║ TEST4 from LordByte SOLVED ║");
- cputs("║ All the hard work was done in 1997 by CR00CK ║");
- cputs("║ The only purpose of this program is to show how bad is this routine ║");
- cputs("║ used in TEST4 ║");
- cputs("║ ONE-TIME PAD ?!? ║");
- cputs("║ Forget about it!!!!!!!! ║");
- cputs("╚══════════════════════════════════════════════════════════════════════════════╝");
- do {
- cputs("How many chars (1 - 12): ");
- scanf("%i", &passchars);
- } while (passchars < 1 || passchars > 12);
- passbits = 8 * passchars;
- cputs("Wait for a while ...");
-
- create_table();
- do_test();
- create_equations();
- solve();
-
- return 0;
- }
-
- void create_table()
- {
- int i, j;
- unsigned char mask, chr, byte[XORCHARS];
- long cipherpos;
- int pass, keychar, bits, xor_char;
- unsigned char buffer[KEYBITS + 1];
-
- if ((org = fopen("CIPHER.DAT", "rb")) != NULL)
- {
- fread(byte, 1, 1, org);
- if (byte[0] == passchars)
- {
- printf("reading from CIPHER.DAT...\n");
- for (i = 0; i < EQUATIONS; i++)
- {
- fread(buffer, KEYBITS+1, 1, org);
- // we cannot use _fmemcpy, coz it fails sometimes on huge tables
- for (j = 0; j <= KEYBITS; j++)
- TabCipher[i][j] = buffer[j];
- }
- fclose(org);
- return;
- }
- }
-
- memset(TabPass, 0, KEYBITS);
- _fmemset(TabKey, 0, KEYSIZE); // initiate TabKey
- for (i = 0; i < passbits; i++) // set passbits bits
- TabKey[i][i] = 1;
- TabKey[passchars*8][KEYBITS] = 0; // char after password is 0x0d
- TabKey[passchars*8+1][KEYBITS] = 0;
- TabKey[passchars*8+2][KEYBITS] = 0;
- TabKey[passchars*8+3][KEYBITS] = 0;
- TabKey[passchars*8+4][KEYBITS] = 1;
- TabKey[passchars*8+5][KEYBITS] = 1;
- TabKey[passchars*8+6][KEYBITS] = 0;
- TabKey[passchars*8+7][KEYBITS] = 1;
- TabKey[13*8][KEYBITS] = 0; // 13th char is 0x0a
- TabKey[13*8+1][KEYBITS] = 0;
- TabKey[13*8+2][KEYBITS] = 0;
- TabKey[13*8+3][KEYBITS] = 0;
- TabKey[13*8+4][KEYBITS] = 1;
- TabKey[13*8+5][KEYBITS] = 0;
- TabKey[13*8+6][KEYBITS] = 1;
- TabKey[13*8+7][KEYBITS] = 0;
- TabKey[14*8][KEYBITS] = 0; // on 14th pos we've got 0x0d
- TabKey[14*8+1][KEYBITS] = 0;
- TabKey[14*8+2][KEYBITS] = 0;
- TabKey[14*8+3][KEYBITS] = 0;
- TabKey[14*8+4][KEYBITS] = 1;
- TabKey[14*8+5][KEYBITS] = 1;
- TabKey[14*8+6][KEYBITS] = 0;
- TabKey[14*8+7][KEYBITS] = 1;
- TabKey[15*8][KEYBITS] = 0; // on 15th there's is 0x20
- TabKey[15*8+1][KEYBITS] = 0;
- TabKey[15*8+2][KEYBITS] = 1;
- TabKey[15*8+3][KEYBITS] = 0;
- TabKey[15*8+4][KEYBITS] = 0;
- TabKey[15*8+5][KEYBITS] = 0;
- TabKey[15*8+6][KEYBITS] = 0;
- TabKey[15*8+7][KEYBITS] = 0;
- passsize = passchars;
-
- if ((org = fopen("ORG.DAT", "rb")) == NULL)
- {
- printf("ORG.DAT not found!\n");
- exit(255);
- }
-
- _fmemset(TabCipher, 0, XORSIZE); // initiate TabCipher
- cipherpos = 0;
- fread(byte, XORCHARS, 1, org);
- fclose(org);
- for (i = 0; i < XORCHARS; i++)
- for (mask = 0x80; mask != 0; mask >>= 1)
- {
- if ((byte[i] & mask) == mask) TabCipher[cipherpos][KEYBITS] = 1;
- cipherpos++;
- }
-
- for (pass = 0; pass < 5; pass++)
- {
- for (keychar = 0; keychar < (passsize - 1); keychar++)
- {
- putch('.');
- memcpy(AktKey, TabKey[keychar*8+24], 8*(KEYBITS+1)); // get current key
- memcpy(AktKey[8], TabKey[keychar*8+16], 8*(KEYBITS+1)); // but reversed
- memcpy(AktKey[16], TabKey[keychar*8+8], 8*(KEYBITS+1));
- memcpy(AktKey[24], TabKey[keychar*8], 8*(KEYBITS+1));
- for (xor_char = 0; xor_char <= (XORCHARS - 4); xor_char++)
- {
- for (bits = 24; bits < 32; bits++)
- do_xor(TabCipher[xor_char * 8 + bits - 24], AktKey[bits]);
- for (bits = 16; bits < 24; bits++)
- do_xor(TabCipher[xor_char * 8 + bits - 8], AktKey[bits]);
- for (bits = 8; bits < 16; bits++)
- do_xor(TabCipher[xor_char * 8 + bits + 8], AktKey[bits]);
- for (bits = 0; bits < 8; bits++)
- do_xor(TabCipher[xor_char * 8 + bits + 24], AktKey[bits]);
- memcpy(Temp, AktKey, 2 * (KEYBITS + 1));
- memmove(AktKey, AktKey[2], 30 * (KEYBITS + 1));
- memcpy(AktKey[30], Temp, 2 * (KEYBITS + 1));
- }
- }
- for (bits = 0; bits < 32; bits++)
- {
- do_xor(TabKey[bits], TabCipher[bits]);
- do_xor(TabKey[32 + bits], TabCipher[bits]);
- do_xor(TabKey[64 + bits], TabCipher[bits]);
- }
- if (pass == 2) set_eax();
- if (passsize < 12) passsize = 14;
- }
-
- if ((org = fopen("CIPHER.DAT", "wb")) != NULL)
- {
- byte[0] = passchars;
- fwrite(byte, 1, 1, org);
- for (i = 0; i < EQUATIONS; i++)
- {
- for (j = 0; j <= KEYBITS; j++)
- // we cannot simply memcpy, coz it doesn't work properly on huge tables
- buffer[j] = TabCipher[i][j];
- fwrite(buffer, KEYBITS+1, 1, org);
- }
- fclose(org);
- }
- }
-
- void set_eax()
- {
- int i;
-
- for (i = 0; i < 32; i++)
- {
- _fmemcpy(TabCipher[XORBITS + i], TabCipher[i], KEYBITS+1);
- _fmemset(TabCipher[i], 0, KEYBITS+1);
- }
- /* this is binary encoded 94, 09, 61, da, all hex */
- TabCipher[0][KEYBITS] = 1;
- TabCipher[1][KEYBITS] = 0;
- TabCipher[2][KEYBITS] = 0;
- TabCipher[3][KEYBITS] = 1;
- TabCipher[4][KEYBITS] = 0;
- TabCipher[5][KEYBITS] = 1;
- TabCipher[6][KEYBITS] = 0;
- TabCipher[7][KEYBITS] = 0;
- TabCipher[8][KEYBITS] = 0;
- TabCipher[9][KEYBITS] = 0;
- TabCipher[10][KEYBITS] = 0;
- TabCipher[11][KEYBITS] = 0;
- TabCipher[12][KEYBITS] = 1;
- TabCipher[13][KEYBITS] = 0;
- TabCipher[14][KEYBITS] = 0;
- TabCipher[15][KEYBITS] = 1;
- TabCipher[16][KEYBITS] = 0;
- TabCipher[17][KEYBITS] = 1;
- TabCipher[18][KEYBITS] = 1;
- TabCipher[19][KEYBITS] = 0;
- TabCipher[20][KEYBITS] = 0;
- TabCipher[21][KEYBITS] = 0;
- TabCipher[22][KEYBITS] = 0;
- TabCipher[23][KEYBITS] = 1;
- TabCipher[24][KEYBITS] = 1;
- TabCipher[25][KEYBITS] = 1;
- TabCipher[26][KEYBITS] = 0;
- TabCipher[27][KEYBITS] = 1;
- TabCipher[28][KEYBITS] = 1;
- TabCipher[29][KEYBITS] = 0;
- TabCipher[30][KEYBITS] = 1;
- TabCipher[31][KEYBITS] = 0;
- }
-
- void do_test()
- {
- int i, mask, bits = 0;
- unsigned char test[123];
-
- memset(password, 0, KEYCHARS);
- printf("\nEnter password to test (%i chars): ", passchars);
- scanf("%12s", password);
- password[passchars]=0xd;
- password[13]=0xa;
- password[14]=0xd;
- password[15]=0x20;
-
- memset(TabPass, 0, KEYBITS);
- for (i = 0; i < KEYCHARS; i++)
- for (mask = 0x80; mask != 0; mask >>= 1)
- {
- if ((password[i] & mask) == mask) TabPass[bits] = 1;
- bits++;
- }
- for (i = 0; i < XORCHARS; i++)
- test[i] = compute_char(i);
- if ((org = fopen("OUT.DAT", "wb")) != NULL)
- {
- fwrite(test, XORCHARS, 1, org);
- fclose(org);
- }
- }
-
- void do_xor(char huge *dest, char huge *source)
- {
- /* int count;
-
- for (count = 0; count <= KEYBITS; count++)
- dest[count] ^= source[count];*/
- asm{
- push ds
- push es
- lds ax,dest
- mov bx,ds
- mov dx,ax
- and ax,15
- mov si,ax
- shr dx,4
- add bx,dx
- mov ds,bx // normalized (offset < 0x10) dest to ds:si
- les ax,source
- mov bx,es
- mov dx,ax
- and ax,15
- mov di,ax
- shr dx,4
- add bx,dx
- mov es,bx // normalized source to es:di
- mov cx,KEYBITS + 1
- }
- petla:
- asm {
- mov al,es:[di]
- xor ds:[si],al
- inc di
- inc si
- loop petla
- pop es
- pop ds
- }
- }
-
- char compute_char(int offset)
- {
- int result = 0, i, bit, mask, bits = 0;
-
- for (mask = 0x80; mask != 0; mask >>= 1) // process all 8 bits
- {
- bit = TabCipher[offset*8+bits][KEYBITS]; // get 1 value (if 1 is set)
- for (i = 0; i < KEYBITS; i++) // process all others
- if (TabCipher[offset*8+bits][i]) bit ^= TabPass[i]; // XOR with password bit
- if (bit) result |= mask;
- bits++;
- }
-
- return result;
- }
-
- unsigned long compute_eax(void)
- {
- int bits = 0, i, bit;
- unsigned long mask = 0x80000000, result = 0;
-
- while (mask != 0)
- {
- bit = AktKey[bits][KEYBITS];
- for (i = 0; i < KEYBITS; i++)
- if (AktKey[bits][i]) bit ^= TabPass[i];
- if (bit) result |= mask;
- bits++;
- mask >>= 1;
- }
- return result;
- }
-
- create_equations(void)
- {
- int i, targetpos = 0;
- unsigned char byte[XORCHARS], mask;
-
- // now, the TabCipher becomes a table where equations to solve are stored
- // first passbits elements are equations itselves, next one is a
- // free word (value on the right side of equation)
-
- if ((org = fopen("XOR.DAT", "rb")) == NULL)
- {
- printf("XOR.DAT not found!\n");
- exit(255);
- }
-
- fread(byte, XORCHARS, 1, org);
- fclose(org);
- for (i = 0; i < XORCHARS; i++)
- for (mask = 0x80; mask != 0; mask >>= 1)
- {
- if ((byte[i] & mask) == mask)
- TabCipher[targetpos][passbits] = 1;
- else
- TabCipher[targetpos][passbits] = 0;
- targetpos++;
- }
- TabCipher[XORBITS][passbits] = 1;
- TabCipher[XORBITS+1][passbits] = 0;
- TabCipher[XORBITS+2][passbits] = 0;
- TabCipher[XORBITS+3][passbits] = 1;
- TabCipher[XORBITS+4][passbits] = 0;
- TabCipher[XORBITS+5][passbits] = 1;
- TabCipher[XORBITS+6][passbits] = 0;
- TabCipher[XORBITS+7][passbits] = 0;
- TabCipher[XORBITS+8][passbits] = 0;
- TabCipher[XORBITS+9][passbits] = 0;
- TabCipher[XORBITS+10][passbits] = 0;
- TabCipher[XORBITS+11][passbits] = 0;
- TabCipher[XORBITS+12][passbits] = 1;
- TabCipher[XORBITS+13][passbits] = 0;
- TabCipher[XORBITS+14][passbits] = 0;
- TabCipher[XORBITS+15][passbits] = 1;
- TabCipher[XORBITS+16][passbits] = 0;
- TabCipher[XORBITS+17][passbits] = 1;
- TabCipher[XORBITS+18][passbits] = 1;
- TabCipher[XORBITS+19][passbits] = 0;
- TabCipher[XORBITS+20][passbits] = 0;
- TabCipher[XORBITS+21][passbits] = 0;
- TabCipher[XORBITS+22][passbits] = 0;
- TabCipher[XORBITS+23][passbits] = 1;
- TabCipher[XORBITS+24][passbits] = 1;
- TabCipher[XORBITS+25][passbits] = 1;
- TabCipher[XORBITS+26][passbits] = 0;
- TabCipher[XORBITS+27][passbits] = 1;
- TabCipher[XORBITS+28][passbits] = 1;
- TabCipher[XORBITS+29][passbits] = 0;
- TabCipher[XORBITS+30][passbits] = 1;
- TabCipher[XORBITS+31][passbits] = 0;
-
- printf("\n");
- for (i = 0; i < EQUATIONS; i++) // if there's one on the left side of the equation
- if (TabCipher[i][KEYBITS])
- TabCipher[i][passbits] ^= 1; // then get rid of it
-
- return 0;
- }
-
- void do_xor_equ(int num1, int num2)
- {
- int i;
-
- for (i = 0; i <= passbits; i++)
- TabCipher[num1][i] ^= TabCipher[num2][i];
- }
-
- void swap_equ(int num1, int num2)
- {
- memcpy(TempEqu, TabCipher[num1], passbits + 1);
- memcpy(TabCipher[num1], TabCipher[num2], passbits + 1);
- memcpy(TabCipher[num2], TempEqu, passbits + 1);
- }
-
- solve()
- {
- int i, j, k, jest, test;
- unsigned char buffer[12 * 8 + 1];
-
- memset(solved, 0, EQUATIONS);
- printf("Solving set of %i equations. This may take while...\n", EQUATIONS);
- for (i = passbits - 1; i >= 0; i--)
- {
- printf("\rProcessing bit %i (out of %i) ", i + 1, passbits);
- jest = 0;
- for (k = 0; k < EQUATIONS; k++)
- if (TabCipher[k][i] && !solved[k])
- {
- jest = 1;
- break;
- }
- if (!jest)
- {
- printf("\nThere is no entry for bit %i\n", i+1);
- continue;
- }
- else
- {
- solved[k] = 1;
- for (j = 0; j < EQUATIONS; j++)
- if ((j != k) && (TabCipher[j][i] == 1))
- do_xor_equ(j, k);
- }
- }
- if ((org = fopen("EQU.DAT", "wb")) != NULL)
- {
- for (i = 0; i < EQUATIONS; i++)
- {
- for (j = 0; j <= passbits; j++)
- // guess, why we aren't using memcpy
- buffer[j] = TabCipher[i][j];
- fwrite(buffer, passbits+1, 1, org);
- }
- fclose(org);
- }
- printf("\nSuccess!!!\n");
- insert_values();
- show_pass(i);
- return 0;
- }
-
- void insert_values()
- {
- int i, j;
- unsigned char bit, bits, have_value[12 * 8], values[12 * 8];
-
- memset(have_value, 0, passbits);
- memset(values, 0, passbits);
- for (i = 0; i < EQUATIONS; i++)
- {
- bits = 0;
- for (j = 0; j < passbits; j++)
- if (TabCipher[i][j])
- {
- bits++;
- bit = j;
- }
- if (bits == 1)
- {
- if (have_value[bit] && values[bit] != TabCipher[i][passbits])
- {
- printf("This set of equations is contradictory!\n");
- return;
- }
- have_value[bit] = 1;
- TabPass[bit] = values[bit] = TabCipher[i][passbits];
- }
- }
- for (i = 0; i < passbits; i++)
- {
- if (!have_value[i]) continue;
- for (j = 0; j < EQUATIONS; j++)
- if (TabCipher[j][i])
- {
- TabCipher[j][i] = 0;
- TabCipher[j][passbits] ^= values[i];
- }
- }
- }
-
- #pragma argsused
- void show_pass(int how_many)
- {
- int bits, i, bitcount;
- unsigned char mask = 0x80, c = 0;
- FILE *passout;
-
- if ((passout = fopen("TEST.OUT", "aw")) != NULL)
- {
- fprintf(passout, "Password chars: %i\n", passchars);
- fprintf(passout, "Sure password chars:\n");
- for (bits = 0; bits < passbits; bits++)
- {
- if (TabPass[bits]) c |= mask;
- mask >>= 1;
- if (mask == 0)
- {
- fprintf(passout, "(%c) - %i\n", c, c);
- mask = 0x80;
- c = 0;
- }
- }
- fclose(passout);
- }
- }
-
- int search(int bit1, int bit2)
- {
- int i;
-
- for (i = 0; i < EQUATIONS; i++)
- if (TabCipher[i][bit1] != TabCipher[i][bit2])
- return i;
- return 0;
- }